package org.cogaen.java2d.xml;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

public class SpriteParser {

	private static final String SPRITE_ELEMENT = "sprite";
	private static final String WIDTH_ATTRIB = "width";
	private static final String HEIGHT_ATTRIB = "height";
	private static final String IMAGE_ATTRIB = "image";
	private static final double DEFAULT_DIMENSION = 0.0;
	private static final String NAME_SPACE = null;
	private double width;
	private double height;
	private String imageName;

	public static boolean isStart(XMLStreamReader reader) {
		return reader.isStartElement() && SPRITE_ELEMENT.equals(reader.getLocalName());
	}
	
	public static ResetableStreamFilter createFilter(String spriteName) {
		return new ElementFilter(SPRITE_ELEMENT, spriteName);
	}

	private void reset() {
		this.width = DEFAULT_DIMENSION;
		this.height = DEFAULT_DIMENSION;
		this.imageName = null;
	}

	public void parse(XMLStreamReader reader) throws XMLStreamException, ParseException {
		reset();
		
		if (isStart(reader)) {
			this.width = parseDimension(reader, WIDTH_ATTRIB);
			this.height = parseDimension(reader, HEIGHT_ATTRIB);
			parseImageName(reader);
		} else {
			throw new ParseException("xml element not found");
		}
	}

	private void parseImageName(XMLStreamReader reader) {
		this.imageName = reader.getAttributeValue(NAME_SPACE, IMAGE_ATTRIB);
	}

	private double parseDimension(XMLStreamReader reader, String attrib) throws ParseException {
		String str = reader.getAttributeValue(NAME_SPACE, attrib);
		
		if (str == null) {
			return DEFAULT_DIMENSION;
		}
		
		try {
			double value = Double.parseDouble(str);
			if (value < 0) {
				throw new ParseException("invalid value for sprite dimension '" + str + "'");				
			}
			return value;
		} catch (NumberFormatException e) {
			throw new ParseException("invalid value for sprite dimension '" + str + "'");
		}		
	}

	public double getWidth() {
		return width;
	}

	public double getHeight() {
		return height;
	}

	public String getImageName() {
		return imageName;
	}
	
}
